#include <iostream>
using namespace std;

namespace zpb
{
    template<class T>
    class shared_ptr
    {
    public:
        shared_ptr(T* ptr = nullptr):_ptr(ptr), _pcount(new int(1))
        {}

        ~shared_ptr()
        {
            if(--(*_pcount) == 0)
            {
                delete _ptr;
                delete _pcount;
            }
        }

        shared_ptr<T>& operator=(const shared_ptr<T>& sp)
        {
            if(_ptr != sp._ptr)
            {
                if(--(*sp._pcount) == 0)
                {
                    delete _ptr;
                    delete _pcount;
                }
                _ptr = sp._ptr;
                _pcount = sp._pcount;
                ++(*_pcount);
            }
            return *this;
        }

        shared_ptr(const shared_ptr<T>& sp):_ptr(sp._ptr), _pcount(sp._pcount)
        {
            ++(*_pcount);
        }

        T& operator*()
        {
            return *_ptr;
        }

        T* operator->()
        {
            return _ptr;
        }
    private:
        T* _ptr;
        int* _pcount;
    };
};

class Date
{
public:
    Date()
    {
        cout << "Date()" << endl;
    }

    ~Date()
    {
        cout << "~Date()" << endl;
    }
private:
};
int main()
{
    zpb::shared_ptr<Date> d1(new Date());
    zpb::shared_ptr<Date> d2(d1);
    zpb::shared_ptr<Date> d3(new Date());
    d1 = d3;
    return 0;
}